#include "ringqueue.hpp"
#include <unistd.h>
using namespace RingQueue;
template <class T>
class Thread
{
public:
    Thread(ringqueue<T> &rq, std::string name) : _name(name), _rq(rq) {}
    ~Thread() {}
    std::string _name;
    ringqueue<T> &_rq;
};
pthread_mutex_t pmutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t cmutex = PTHREAD_MUTEX_INITIALIZER;
int count = 1;
void *produce(void *args)
{
    Thread<int> *pthread = static_cast<Thread<int> *>(args);
    while (true)
    {
        // 生产数据
        pthread_mutex_lock(&pmutex);
        pthread->_rq.Produce(count);
        std::cout << pthread->_name << " 生产了一个数据 : " << count << std::endl;
        count++;
        pthread_mutex_unlock(&pmutex);
        sleep(1);
    }
    return (void *)"1";
}
void *consume(void *args)
{
    Thread<int> *pthread = static_cast<Thread<int> *>(args);
    while (true)
    {
        // 消费数据
        sleep(1);
        pthread_mutex_lock(&cmutex);
        int msg = 0;
        pthread->_rq.Consume(msg);
        std::cout << pthread->_name << " 消费了一个数据 : " << msg << std::endl;
        pthread_mutex_unlock(&cmutex);
    }
    return (void *)"0";
}

int main()
{
    pthread_t t1, t2, t3, t4;
    ringqueue<int> rq;
    // t1,t2生产
    Thread td1(rq, "thread-1 ");
    pthread_create(&t1, nullptr, produce, &td1);
    Thread td2(rq, "thread-2 ");
    pthread_create(&t2, nullptr, produce, &td2);

    // t3,t4消费
    Thread td3(rq, "thread-3 ");
    pthread_create(&t3, nullptr, consume, &td3);
    Thread td4(rq, "thread-4 ");
    pthread_create(&t3, nullptr, consume, &td4);

    pthread_join(t1, nullptr);
    pthread_join(t2, nullptr);
    pthread_join(t3, nullptr);
    pthread_join(t4, nullptr);
    return 0;
}

// using namespace RingQueue;

// struct Thread
// {
//     Thread(ringqueue<int> &rq, std::string name) : _rq(rq), _name(name) {}
//     ringqueue<int> &_rq;
//     std::string _name;
// };
// int msg = 1;
// void *write(void *args)
// {
//     Thread *td = static_cast<Thread *>(args);

//     while (true)
//     {
//         sleep(1);
//         td->_rq.Produce(msg);
//         std::cout << td->_name << "生产了一个信息 : " << msg++ << std::endl;
//     }
// }
// void *read(void *args)
// {
//     Thread *td = static_cast<Thread *>(args);
//     int msg = 0;
//     while (true)
//     {
//         // sleep(1);
//         td->_rq.Consume(&msg);
//         std::cout << td->_name << "消费了一个信息 : " << msg << std::endl;
//     }
// }

// int main()
// {
//     pthread_t t1, t2, t3, t4;
//     ringqueue<int> rq;
//     // t1,t2生产
//     Thread td1(rq, "thread-1 ");
//     pthread_create(&t1, nullptr, write, &td1);
//     Thread td2(rq, "thread-2 ");
//     pthread_create(&t2, nullptr, write, &td2);

//     // t3,t4消费
//     Thread td3(rq, "thread-3 ");
//     pthread_create(&t3, nullptr, read, &td3);
//     Thread td4(rq, "thread-4 ");
//     pthread_create(&t3, nullptr, read, &td4);

//     pthread_join(t1, nullptr);
//     pthread_join(t2, nullptr);
//     pthread_join(t3, nullptr);
//     pthread_join(t4, nullptr);
//     return 0;
// }

// int main()
// {
//     pthread_t t1, t2;
//     ringqueue<int> rq;
//     Thread td1(rq, "thread-1 ");
//     // t1写
//     pthread_create(&t1, nullptr, write, &td1);
//     Thread td2(rq, "thread-2 ");
//     // t2写
//     pthread_create(&t2, nullptr, read, &td2);

//     pthread_join(t1, nullptr);
//     pthread_join(t2, nullptr);
//     return 0;
// }